#include "workprocess.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "systemdata.h"
#include "wakeup.h"
#include "delay.h"
#include "powermanage.h"
#include "drv_timer.h"
#include "main.h"
#include "bat_afe.h"

typedef struct{
	uint8_t pre_start_flag;
	uint8_t pre_chg_ok_flag;
	uint16_t pre_chg_time_ms;
}PreChgCtrlData_t;

static PreChgCtrlData_t pre_chg_data = {.pre_start_flag = 0,.pre_chg_ok_flag = 0,.pre_chg_time_ms = 0};
static SysConfData_t *confinfo = NULL;
static SysRunData_t  *runinfo = NULL;
static Timer_t		 *work_process_timer_1ms = NULL;//状态切换计时定时器
static uint16_t sleep_delay_time_ms = 0;

static void charge_policy_process(void){
	runinfo->chgReqVol = confinfo->fctData.batNum;
	if(confinfo->fctData.batType == sanyuanBat){//如果是三元,请求电压为4.2×串数		
		runinfo->chgReqVol *= 420;//单位:0.01V
	}else if(confinfo->fctData.batType == lstlBat){
		runinfo->chgReqVol *= 365;//单位:0.01V		
	}else if(confinfo->fctData.batType == nslBat){
		runinfo->chgReqVol *= 395;
	}
	if((runinfo->chgReqVol%10) != 0){
		runinfo->chgReqVol += 10;
	}
	runinfo->chgReqVol /= 10;
	runinfo->chgReqCur = confinfo->errorData.chgOverCurrent.value*90/10;//请求电流为一级充电过流值的90%,单位:0.1A
}

uint8_t sleep_enter_control(void){
	if(runinfo->batState == chgState || runinfo->batState == dsgState){//如果是充放电状态,不允许休眠
		return 0;
	}else{
		runinfo->sleep_flag = 1;
		return 1;
	}
	
	return 0;
}

static void pre_charge_process(void){
	uint8_t res = 0;
	if(runinfo->sysSwState.bits.SW_PRE == 0){
		afe_prechg_mos_ctrl(true);
	}
	if(pre_chg_data.pre_chg_ok_flag == 0){
		pre_chg_data.pre_start_flag = 1;
		if(pre_chg_data.pre_chg_time_ms >= (uint32_t)confinfo->fctData.preChargeTime.value){
			printf("prepare charge ok!\n");
			pre_chg_data.pre_chg_ok_flag = 1;
			pre_chg_data.pre_start_flag = 0;
			pre_chg_data.pre_chg_time_ms = 0;
		}
	}else{
		pre_chg_data.pre_chg_time_ms = 0;
		pre_chg_data.pre_start_flag = 0;
	}
}


static void pre_charge_time_ctrl(void *data){
	if(pre_chg_data.pre_start_flag == 1){
		pre_chg_data.pre_chg_time_ms += *(uint32_t *)data;
	}else{
		pre_chg_data.pre_chg_time_ms = 0;
	}
}

static void poweroff_process(void){
	afe_dsg_mos_ctrl(false);
	afe_prechg_mos_ctrl(false);
	afe_chg_mos_ctrl(false);
	runinfo->batState = slpState;
	if(sleep_delay_time_ms <= 600){//比上位机的查询周期多100ms
		return;
	}
	sleep_delay_time_ms = 0;
	system_poweroff();
}


static void sleep_delay_ctrl(void *data){
	if(runinfo->sleep_flag == 1 || runinfo->poweroff_flag == 1){
		sleep_delay_time_ms += *(uint32_t *)data;
	}else{
		sleep_delay_time_ms = 0;
	}
}

static void reset_precharge_state(void){
	pre_chg_data.pre_start_flag = 0;
	pre_chg_data.pre_chg_ok_flag = 0;
	pre_chg_data.pre_chg_time_ms = 0;
}

static void state_manager_process(void){
	//汇总充放电相关的故障
	uint8_t chg_error = runinfo->afeProtByte.byte|
						runinfo->curProtByte.bit.chgCUr1Prot|	//充电过流
						runinfo->curProtByte.bit.chgCur2Prot|
						runinfo->curProtByte.bit.chgCur3Prot|
						(bool)runinfo->volProtByte.cellHgVolProt|	//单体过压
						runinfo->volProtByte.volProt.bit.afeVolHgProt|	//单体二级过压
						runinfo->volProtByte.volProt.bit.packVolHgProt|	//总压过压
						runinfo->tempProtByte.bit.chgTempLowProt|	//充电低温
						runinfo->tempProtByte.bit.chgTempHgProt| 	//充电过温
						runinfo->tempProtByte.bit.mosTempHgProt|	//MOS过温
						runinfo->tempProtByte.bit.envTempHgProt|//环境高温保护
						runinfo->tempProtByte.bit.envTempLowProt|//环境低温保护
						runinfo->tempProtByte.bit.tempDiffProt;//温差保护
	
	uint8_t dsg_error = runinfo->afeProtByte.byte|
						runinfo->curProtByte.bit.disCur1Prot|	//放电过流
						runinfo->curProtByte.bit.disCur2Prot|
						runinfo->curProtByte.bit.disCur3Prot|
						runinfo->curProtByte.bit.disCur4Prot|
						runinfo->curProtByte.bit.shortCurProt| 	//短路
						(bool)runinfo->volProtByte.cellLowVolProt|	//单体欠压
						runinfo->volProtByte.volProt.bit.afeVolLowProt|	//单体二级欠压
						runinfo->volProtByte.volProt.bit.packVolLowProt|	//总压欠压
						runinfo->tempProtByte.bit.disTempLowProt|	//放电低温
						runinfo->tempProtByte.bit.disTempHgProt| 	//放电过温
						runinfo->tempProtByte.bit.mosTempHgProt|	//MOS过温
						runinfo->tempProtByte.bit.envTempHgProt|    //环境高温保护
						runinfo->tempProtByte.bit.envTempLowProt|   //环境低温保护
						runinfo->tempProtByte.bit.tempDiffProt|     //温差保护
						runinfo->volProtByte.volProt.bit.cellVolDiffProt;     //压差保护
								

//先通过电流、钥匙信号判断充放电状态
	uint8_t chg_flag = 0;
	uint8_t dsg_flag = 0;
	int16_t wakeupCur = confinfo->fctData.wakeupCurrent.value;
	if(abs(runinfo->batCur) > wakeupCur){//电流大于唤醒值
		if(runinfo->batCur > 0){//电流为正，此时充电MOS一定是开的
			chg_flag = 1;
		}else{
			dsg_flag = 1;
		}
	}else{
		chg_flag = 0;
		dsg_flag = 0;
	}

	if((runinfo->funcSwState.bits.SW_CHG_EN | runinfo->funcSwState.bits.SW_DSG_EN) == 0){
		afe_prechg_mos_ctrl(false);
		afe_chg_mos_ctrl(false);
		afe_dsg_mos_ctrl(false);
		chg_flag = 0;
		dsg_flag = 0;
	}

	//根据充电允许、故障等信息，控制充电MOS状态
	if(dsg_flag == 1 || (runinfo->funcSwState.bits.SW_CHG_EN == 1 && chg_error == 0)){
		afe_chg_mos_ctrl(true);
		afe_chglimit_mos_ctrl(false);	
	}else{
		afe_chg_mos_ctrl(false);
		afe_chglimit_mos_ctrl(false);
	}
	//根据放电允许、故障等信息，控制放电MOS状态
	if(chg_flag == 1){
		if(pre_chg_data.pre_chg_ok_flag == 0){
			pre_charge_process();
		}else{
			afe_dsg_mos_ctrl(true);
			afe_prechg_mos_ctrl(false);
		}
	}else if(runinfo->funcSwState.bits.SW_DSG_EN == 1 && dsg_error == 0){
		if(confinfo->fctData.otherParmByte.bit.key_check_enable){//钥匙信号
			if(get_keywake()==true){
				if(pre_chg_data.pre_chg_ok_flag == 0){
					pre_charge_process();
				}else{
					afe_dsg_mos_ctrl(true);
					afe_prechg_mos_ctrl(false);
				}
			}else{//没有检测到钥匙信号
				afe_dsg_mos_ctrl(false);
				reset_precharge_state();
				afe_prechg_mos_ctrl(false);
			}
		}else{
			if(confinfo->fctData.otherParmByte.bit.chag_pwr_prchg_enable){//如果设置为换电用
				if(runinfo->comLinkState.Bits.chgCbtOutTimeState){
					afe_dsg_mos_ctrl(false);
					afe_prechg_mos_ctrl(true);
					if(read_load_det()==true){
						if(pre_chg_data.pre_chg_ok_flag == 0){
							pre_charge_process();
						}else{
							afe_dsg_mos_ctrl(true);
							afe_prechg_mos_ctrl(false);
							runinfo->comLinkState.Bits.chgCbtOutTimeState = 0;
						}
					}else{
						reset_precharge_state();
					}			
				}else{
					afe_dsg_mos_ctrl(true);
					afe_prechg_mos_ctrl(false);
				}
			}else{
				if(pre_chg_data.pre_chg_ok_flag == 0){
					pre_charge_process();
				}else{
					afe_dsg_mos_ctrl(true);
					afe_prechg_mos_ctrl(false);
				}		
			}			
		}
	}else{
		afe_dsg_mos_ctrl(false);
		reset_precharge_state();
		afe_prechg_mos_ctrl(false);
	}
	//更新电池当前状态
	if(chg_flag == 1){
		runinfo->batState = chgState;
	}else if(dsg_flag == 1){
		runinfo->batState = dsgState;
	}else{
		uint32_t errorState = 0;
		errorState |= runinfo->tempProtByte.byte;//温度故障状态
		errorState |= runinfo->curProtByte.byte;//电流故障状态
		errorState |= runinfo->volProtByte.volProt.byte;//电压故障状态
		errorState |= runinfo->afeProtByte.byte;//模拟前端故障状态
		errorState |= runinfo->volProtByte.cellHgVolProt;//单体过压故障状态
		errorState |= runinfo->volProtByte.cellLowVolProt;//单体欠压故障状态
		if(errorState==0){
			runinfo->batState = stdState;
		}else{
			runinfo->batState = errState;
		}
	}
	saveSystemErrorRecord();//保存故障记录
}


#define CELL_POWEROFF_TIME	(1000*60*30)	//30分钟
//#define CELL_POWEROFF_TIME	3000	//30分钟

static void auto_poweroff_ctrl(void *data){
	static uint32_t power_enter_wait_time = 0;
	//没有充放电且单体最低电压低于关机电压，开始计时
	if((runinfo->batMinVol < confinfo->fctData.poweroff_vol.value) && (runinfo->batState != chgState) && (runinfo->batState != dsgState)){
		power_enter_wait_time += *(uint32_t *)data;
		
	}else{
		power_enter_wait_time = 0;
	}
	if(power_enter_wait_time >= CELL_POWEROFF_TIME){//30分钟
		if(runinfo->sysSwState.bits.SW_OTA != 0){
			power_enter_wait_time = CELL_POWEROFF_TIME;
			return;
		}
		power_enter_wait_time = 0;
		runinfo->poweroff_flag = 1;
	}
}

void work_task_process(void){
	if(runinfo->sleep_flag == 0 && runinfo->poweroff_flag == 0){
		charge_policy_process();
		state_manager_process();
	}else{
		poweroff_process();
	}
}
	
static void work_timer_1ms_callback(void *data){
	pre_charge_time_ctrl(data);
	auto_poweroff_ctrl(data);
	sleep_delay_ctrl(data);
}

void work_task_init(void){
	confinfo = getSysConfData();
	runinfo = getSysRunData();
	runinfo->active_flag = 0;
	runinfo->batState = stdState;
	work_process_timer_1ms = timer_create(work_timer_1ms_callback,1);
	timer_start(work_process_timer_1ms);
//	runinfo->comLinkState.Bits.chgCbtOutTimeState = 1;
//	confinfo->fctData.otherParmByte.bit.chag_pwr_prchg_enable = 1;
}